package org.taobao.ibatiside.ui.wizard;

import java.beans.PropertyChangeEvent;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.eclipse.core.databinding.Binding;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.datatools.modelbase.sql.query.QuerySelectStatement;
import org.eclipse.datatools.sqltools.core.profile.ProfileUtil;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.databinding.EMFDataBindingContext;
import org.eclipse.emf.databinding.EMFObservables;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.search.IJavaSearchConstants;
import org.eclipse.jface.databinding.swt.ISWTObservableValue;
import org.eclipse.jface.databinding.swt.SWTObservables;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.ColumnLabelProvider;
import org.eclipse.jface.viewers.ComboViewer;
import org.eclipse.jface.viewers.EditingSupport;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.jface.viewers.TextCellEditor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.Text;
import org.eclipse.wb.swt.SWTResourceManager;
import org.eclipse.wst.xml.ui.internal.properties.StringComboBoxCellEditor;
import org.taobao.ibatiside.model.mapperv2.Discriminator;
import org.taobao.ibatiside.model.mapperv2.Mapperv2Factory;
import org.taobao.ibatiside.model.mapperv2.Mapperv2Package;
import org.taobao.ibatiside.model.mapperv2.Result;
import org.taobao.ibatiside.model.mapperv2.ResultMap;
import org.taobao.ibatiside.model.mapperv2.SqlMap;
import org.taobao.ibatiside.model.mapperv2.TypeAlias;
import org.taobao.ibatiside.ui.util.ClassField;
import org.taobao.ibatiside.ui.util.MiscHelper;
import org.taobao.ibatiside.ui.util.TypeWrapper;
import org.taobao.ibatiside.ui.util.WorkspaceUtil;

import uk.ac.shef.wit.simmetrics.similaritymetrics.MongeElkan;
import uk.ac.shef.wit.simmetrics.tokenisers.TokeniserIbatisId;

public abstract class NewResultMapComposite extends PageComposite {
	private Table table;
	private Text groupByValue;
	private Text xmlNameValue;
	private Text idValue;
	private Label lbDisci;
	private Button btnNewDiscriminator;
	ResultMap newResultMap;
	private List<TypeWrapper> typeWrappers;
	
	private Binding idBinding;
	private Binding groupByBinding;
	private Binding xmlNameBinding;
	private ComboViewer comboExtendsViewer;
	private ComboViewer comboMapClassViewer;
	private TableViewer resultViewer;
	private String[] propertyItems = ArrayUtils.EMPTY_STRING_ARRAY;
	private MongeElkan simiME = new MongeElkan(new TokeniserIbatisId());
	public static final class ResultWrapper {
		final Result internalResult;
		boolean inherited;
		public ResultWrapper(Result internalResult) {
			super();
			this.internalResult = internalResult;
		}
	}
	private List<ResultWrapper> resultWrappers = new LinkedList<NewResultMapComposite.ResultWrapper>();
	private TableViewerColumn propertyColumnViewer;
	public NewResultMapComposite(Composite parent, int style) {
		super(parent, style);
		
	}

	public NewResultMapComposite(Composite parent, int style,
			BatisCommonPage page) {
		super(parent, style, page);
	}


	@Override
	protected void checkSubclass() {
		
	}

	@Override
	protected void createContent() {
		initTypeWrappers();
		setLayout(new GridLayout(1, false));
		Composite composite = new Composite(this, SWT.NONE);
		FormLayout fl_composite = new FormLayout();
		fl_composite.spacing = 2;
		composite.setLayout(fl_composite);
		GridData gd_composite = new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1);
		gd_composite.heightHint = 60;
		composite.setLayoutData(gd_composite);
		
		Label lblId = new Label(composite, SWT.NONE);
		lblId.setAlignment(SWT.RIGHT);
		FormData fd_lblId = new FormData();
		fd_lblId.top = new FormAttachment(0, 10);
		fd_lblId.left = new FormAttachment(0);
		fd_lblId.right = new FormAttachment(0, 30);
		lblId.setLayoutData(fd_lblId);
		lblId.setText("ID");
		
		idValue = new Text(composite, SWT.BORDER);
		FormData fd_idValue = new FormData();
		fd_idValue.top = new FormAttachment(0,6);
		fd_idValue.left = new FormAttachment(lblId,5);
		idValue.setLayoutData(fd_idValue);
		
		
		Label lblClass = new Label(composite, SWT.NONE);
		FormData fd_lblClass = new FormData();
		fd_lblClass.left = new FormAttachment(idValue, 6);
		fd_lblClass.top = new FormAttachment(0, 10);
		lblClass.setLayoutData(fd_lblClass);
		lblClass.setText("Class");
		
		comboMapClassViewer = new ComboViewer(composite, SWT.NONE);
		comboMapClassViewer.addSelectionChangedListener(new ISelectionChangedListener() {
			public void selectionChanged(SelectionChangedEvent event) {
				{
					//alias, select and dataobject
					if (!event.getSelection().isEmpty()){
						TypeWrapper tw = (TypeWrapper) ((IStructuredSelection)event.getSelection()).getFirstElement();
						int cate = tw.getCategory();
						if (cate == TypeWrapper.TYPE_ALIAS){
							TypeAlias fqn = MiscHelper.getAliasByLiteral(model.getSqlmap(), tw.getTypeLiteral());
							if (fqn != null){
								try {
									IType alias_type = model.getCurrentProject().findType(fqn.getType());
									if (alias_type != null){
										newResultMap.setClass(fqn.getAlias());
										setFields(MiscHelper.loadWritableFields(alias_type));
									}else{
										hostPage.setErrorMessage("Can't find type '"+fqn.getType()+"' for alias '"+fqn.getAlias()+"', please check it!");
									}
								} catch (JavaModelException e) {
									e.printStackTrace();
									hostPage.setErrorMessage("can't find alias "+tw.getTypeLiteral());
								}
							}
						}else if (cate == TypeWrapper.NEW_CREATE){
							if (model.getBeanNeedCreate()){
								newResultMap.setClass(WorkspaceUtil.getClassPathString(model.getConfigurationFile().getProject(), model.getBeanPath()));
								setFields(MiscHelper.toBeClassField(model.getBeanFields()));
							}
						}else if (cate == TypeWrapper.SELECT){
							IType selected_type = WorkspaceUtil.openType2(getShell(),model.getCurrentProject(),false);
							if (selected_type != null){
								try {
									newResultMap.setClass(selected_type.getFullyQualifiedName());
									setFields(MiscHelper.loadJavaBeanFields(selected_type));
								} catch (JavaModelException e) {
									e.printStackTrace();
									hostPage.setErrorMessage("can't load bean "+selected_type.getFullyQualifiedName());
								}
							}
						}
					}
				}
			}
		});
		Combo comboMapClass = comboMapClassViewer.getCombo();
		FormData fd_comboMapClass = new FormData();
		fd_comboMapClass.top = new FormAttachment(0, 5);
		fd_comboMapClass.right = new FormAttachment(40);
		fd_comboMapClass.left = new FormAttachment(lblClass);
		comboMapClass.setLayoutData(fd_comboMapClass);
		
		
		Label lblDiscriminator = new Label(composite, SWT.NONE);
		FormData fd_lblDiscriminator = new FormData();
		fd_lblDiscriminator.left = new FormAttachment(comboMapClass);
		fd_lblDiscriminator.top = new FormAttachment(0,6);
		lblDiscriminator.setLayoutData(fd_lblDiscriminator);
		lblDiscriminator.setText("Discriminator");
		
		lbDisci = new Label(composite, SWT.NONE);
		lbDisci.setForeground(SWTResourceManager.getColor(SWT.COLOR_RED));
		FormData fd_lbDisci = new FormData();
		fd_lbDisci.top = new FormAttachment(0, 8);
		
		
		btnNewDiscriminator = new Button(composite, SWT.NONE);
		btnNewDiscriminator.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				NewDiscriminatorDialog new_dialog = new NewDiscriminatorDialog(getShell());
				new_dialog.setResultWrappers(extractColumns());
				if (new_dialog.open() == NewDiscriminatorDialog.OK){
					Discriminator discriminator = new_dialog.discriminator;
					newResultMap.setDiscriminator(discriminator);
					lbDisci.setText(discriminator.getColumn());
				}
			}
		});
		
		fd_lbDisci.left = new FormAttachment(lblDiscriminator, 3);
		fd_lbDisci.right = new FormAttachment(btnNewDiscriminator);
		lbDisci.setLayoutData(fd_lbDisci);
		
		FormData fd_btnNewDiscriminator = new FormData();
		fd_btnNewDiscriminator.top = new FormAttachment(0, 4);
		fd_btnNewDiscriminator.right = new FormAttachment(100);
		btnNewDiscriminator.setLayoutData(fd_btnNewDiscriminator);
		btnNewDiscriminator.setText("New Discriminator");
		
		Label lblExtends = new Label(composite, SWT.NONE);
		FormData fd_lblExtends = new FormData();
		fd_lblExtends.left = new FormAttachment(0, 5);
		fd_lblExtends.top = new FormAttachment(lblId, 10);
		lblExtends.setLayoutData(fd_lblExtends);
		lblExtends.setText("Extends");
		
		comboExtendsViewer = new ComboViewer(composite, SWT.NONE);
		comboExtendsViewer.addSelectionChangedListener(new ISelectionChangedListener() {
			public void selectionChanged(SelectionChangedEvent event) {
				if (!event.getSelection().isEmpty()){
					ResultMap parent_map = (ResultMap) ((IStructuredSelection)event.getSelection()).getFirstElement();
					newResultMap.setExtends(parent_map);
					recalcResults();
				}
			}
		});
		Combo comboExtends = comboExtendsViewer.getCombo();
		FormData fd_comboExtends = new FormData();
		fd_comboExtends.right = new FormAttachment(30);
		fd_comboExtends.left = new FormAttachment(lblExtends, 5);
		fd_comboExtends.top = new FormAttachment(idValue, 5);
		comboExtends.setLayoutData(fd_comboExtends);
		
		Label lblGroupBy = new Label(composite, SWT.NONE);
		FormData fd_lblGroupBy = new FormData();
		fd_lblGroupBy.top = new FormAttachment(idValue, 10);
		fd_lblGroupBy.left = new FormAttachment(comboExtends);
		lblGroupBy.setLayoutData(fd_lblGroupBy);
		lblGroupBy.setText("Group By");
		
		groupByValue = new Text(composite, SWT.BORDER);
		FormData fd_groupByValue = new FormData();
		fd_groupByValue.right = new FormAttachment(60);
		fd_groupByValue.top = new FormAttachment(idValue, 6);
		fd_groupByValue.left = new FormAttachment(lblGroupBy);
		groupByValue.setLayoutData(fd_groupByValue);
		
		Label lblXmlName = new Label(composite, SWT.NONE);
		FormData fd_lblXmlName = new FormData();
		fd_lblXmlName.left = new FormAttachment(groupByValue, 6);
		fd_lblXmlName.top = new FormAttachment(idValue,10);
		lblXmlName.setLayoutData(fd_lblXmlName);
		lblXmlName.setText("Xml Name");
		
		xmlNameValue = new Text(composite, SWT.BORDER);
		FormData fd_xmlNameValue = new FormData();
		fd_xmlNameValue.right = new FormAttachment(100, -10);
		fd_xmlNameValue.left = new FormAttachment(lblXmlName);
		fd_xmlNameValue.top = new FormAttachment(idValue,6);
		xmlNameValue.setLayoutData(fd_xmlNameValue);
		
	
		resultViewer = new TableViewer(this, SWT.BORDER | SWT.FULL_SELECTION);
		table = resultViewer.getTable();
		table.setLinesVisible(true);
		table.setHeaderVisible(true);
		GridData gd_table = new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1);
		gd_table.widthHint = 664;
		table.setLayoutData(gd_table);
		
		TableViewerColumn tableViewerColumn = new TableViewerColumn(resultViewer, SWT.NONE);
		tableViewerColumn.setLabelProvider(new ColumnLabelProvider() {
			public Image getImage(Object element) {
				return null;
			}
			public String getText(Object element) {
				return element == null ? "" : ((ResultWrapper)element).internalResult.getColumn();
			}
		});
		TableColumn tblclmnNewColumn = tableViewerColumn.getColumn();
		tblclmnNewColumn.setWidth(123);
		tblclmnNewColumn.setText("Column");
		
		TableViewerColumn tableViewerColumn_1 = new TableViewerColumn(resultViewer, SWT.NONE);
		tableViewerColumn_1.setLabelProvider(new ColumnLabelProvider() {
			public Image getImage(Object element) {
				return null;
			}
			public String getText(Object element) {
				return element == null ? "" : ((ResultWrapper)element).internalResult.getColumnIndex().toString();
			}
		});
		TableColumn tblclmnNewColumn_1 = tableViewerColumn_1.getColumn();
		tblclmnNewColumn_1.setWidth(46);
		tblclmnNewColumn_1.setText("Index");
		
		propertyColumnViewer = new TableViewerColumn(resultViewer, SWT.NONE);
		propertyColumnViewer.setEditingSupport(new EditingSupport(resultViewer) {
			protected boolean canEdit(Object element) {
				return !((ResultWrapper)element).inherited;
			}
			protected CellEditor getCellEditor(Object element) {
				return new StringComboBoxCellEditor(table, propertyItems);
			}
			protected Object getValue(Object element) {
				return StringUtils.defaultString(((ResultWrapper)element).internalResult.getProperty());
			}
			protected void setValue(Object element, Object value) {
				String str = (String) value;
				if (StringUtils.isNotBlank(str)){
					((ResultWrapper)element).internalResult.setProperty(str);
					resultViewer.update(element, null);
				}
			}
		});
		propertyColumnViewer.setLabelProvider(new ColumnLabelProvider() {
			public Image getImage(Object element) {
				return null;
			}
			public String getText(Object element) {
				return element == null ? "" : ((ResultWrapper)element).internalResult.getProperty();
			}
		});
		TableColumn tblclmnProperty = propertyColumnViewer.getColumn();
		tblclmnProperty.setWidth(124);
		tblclmnProperty.setText("Property");
		
		TableViewerColumn tableViewerColumn_4 = new TableViewerColumn(resultViewer, SWT.NONE);
		tableViewerColumn_4.setLabelProvider(new ColumnLabelProvider() {
			public Image getImage(Object element) {
				return null;
			}
			public String getText(Object element) {
				return element == null ? "" : ((ResultWrapper)element).internalResult.getNullValue();
			}
		});
		tableViewerColumn_4.setEditingSupport(new EditingSupport(resultViewer) {
			protected boolean canEdit(Object element) {
				return !((ResultWrapper)element).inherited;
			}
			protected CellEditor getCellEditor(Object element) {
				return new TextCellEditor(table);
			}
			protected Object getValue(Object element) {
				return StringUtils.defaultString(((ResultWrapper)element).internalResult.getNullValue());
			}
			protected void setValue(Object element, Object value) {
				String str= (String) value;
				if (StringUtils.isNotBlank(str)){
					((ResultWrapper)element).internalResult.setNullValue(str);
					resultViewer.update(element, null);
				}
			}
		});
		TableColumn tblclmnNullValue = tableViewerColumn_4.getColumn();
		tblclmnNullValue.setWidth(116);
		tblclmnNullValue.setText("Null Value");
		
		TableViewerColumn tableViewerColumn_2 = new TableViewerColumn(resultViewer, SWT.NONE);
		tableViewerColumn_2.setEditingSupport(new EditingSupport(resultViewer) {
			protected boolean canEdit(Object element) {
				return !((ResultWrapper)element).inherited;
			}
			protected CellEditor getCellEditor(Object element) {
				return new TypeSelectionCellEditor(((ResultWrapper)element).internalResult.getTypeHandler(),table, model.getCurrentProject(), IJavaSearchConstants.TYPE);
			}
			protected Object getValue(Object element) {
				String fqn = ((ResultWrapper)element).internalResult.getTypeHandler();
				if (null != fqn){
					try {
						return model.getCurrentProject().findType(fqn);
					} catch (JavaModelException e) {
						e.printStackTrace();
					}
				}
				return null;
			}
			protected void setValue(Object element, Object value) {
				if (element != null && value != null){
					String fqn = ((IType)value).getFullyQualifiedName();
					((ResultWrapper)element).internalResult.setTypeHandler(fqn);
					resultViewer.update(element, null);
				}
			}
		});
		tableViewerColumn_2.setLabelProvider(new ColumnLabelProvider() {
			public Image getImage(Object element) {
				return null;
			}
			public String getText(Object element) {
				return element == null ? "" : ((ResultWrapper)element).internalResult.getTypeHandler();
			}
		});
		TableColumn tblclmnTypeHandler = tableViewerColumn_2.getColumn();
		tblclmnTypeHandler.setWidth(242);
		tblclmnTypeHandler.setText("Type Handler");
		
		Composite composite_1 = new Composite(this, SWT.NONE);
		composite_1.setLayout(new FormLayout());
		GridData gd_composite_1 = new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1);
		gd_composite_1.heightHint = 28;
		composite_1.setLayoutData(gd_composite_1);
		
		Button btnCreate = new Button(composite_1, SWT.CENTER);
		btnCreate.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				if (allRight()){
					cropResultMap();
					getDisplay().asyncExec(new Runnable() {
						public void run() {
							okPressed();
						}
					});
				}else{
					hostPage.setErrorMessage("Info is not completed or right!");
				}
			}
		});
		FormData fd_btnCreate = new FormData();
		fd_btnCreate.right = new FormAttachment(50, -3);
		fd_btnCreate.top = new FormAttachment(0);
		btnCreate.setLayoutData(fd_btnCreate);
		btnCreate.setText("Create");
		
		Button btnClose = new Button(composite_1, SWT.NONE);
		btnClose.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				getDisplay().asyncExec(new Runnable() {
					public void run() {
						cancelPressed();
					}
				});
			}
		});
		FormData fd_btnClose = new FormData();
		fd_btnClose.left = new FormAttachment(btnCreate, 3);
		btnClose.setLayoutData(fd_btnClose);
		btnClose.setText("Close");
		
		comboExtendsViewer.setContentProvider(new ArrayContentProvider());
		comboExtendsViewer.setLabelProvider(new LabelProvider(){
			@Override
			public String getText(Object element) {
				return ((ResultMap)element).getId();
			}
		});
		
		comboMapClassViewer.setContentProvider(new ArrayContentProvider());
		comboMapClassViewer.setLabelProvider(new TypeWrapperLabelProvider());
		comboMapClassViewer.setInput(typeWrappers);
		
		resultViewer.setContentProvider(new ArrayContentProvider());
		resultViewer.setInput(resultWrappers);
	}


	protected String[] extractColumns() {
		List<String> cols = new LinkedList<String>();
		for (ResultWrapper w : resultWrappers){
			if (!w.inherited){
				cols.add(w.internalResult.getColumn());
			}
		}
		return cols.toArray(new String[cols.size()]);
	}

	protected void recalcResults() {
		
	}

	protected void cropResultMap() {
		String disc = newResultMap.getDiscriminator() != null ? newResultMap.getDiscriminator().getColumn() : null;
		for (ResultWrapper wrapper : resultWrappers){
			if (!wrapper.inherited && !wrapper.internalResult.getColumn().equals(disc)){
				newResultMap.getResult().add(wrapper.internalResult);
			}
		}
		if (StringUtils.isBlank(newResultMap.getGroupBy())){
			newResultMap.setGroupBy(null);
		}
		if (StringUtils.isBlank(newResultMap.getXmlName())){
			newResultMap.setXmlName(null);
		}
	}
	public static final float UNDEFINED_FLOAT = -100.0F;
	protected void setFields(List<ClassField> loadJavaBeanFields) {
		//update result field if we found similarity;
		propertyItems = new String[loadJavaBeanFields.size()];
		for (int i = 0; i < loadJavaBeanFields.size(); i++){
			propertyItems[i] = loadJavaBeanFields.get(i).getFieldName();
		}
		boolean[] matched = new boolean[propertyItems.length];
		for (ResultWrapper wrapper : resultWrappers){
			
			if (!wrapper.inherited){
				String col_name = wrapper.internalResult.getColumn();
				float max = UNDEFINED_FLOAT;
				int simi_index = -100;
				for (int i =0 ; i < propertyItems.length; i++){
					if (matched[i]) continue;
					float result = simiME.getSimilarity(col_name, propertyItems[i]);
					if (result > max){
						max = result;
						simi_index = i;
					}
				}
				if (max != UNDEFINED_FLOAT){
					wrapper.internalResult.setProperty(propertyItems[simi_index]);
					matched[simi_index] = true;
				}
			}
		}
		resultViewer.refresh();
	}

	private void initTypeWrappers() {
		typeWrappers = new ArrayList<TypeWrapper>();
		typeWrappers.add(MiscHelper.TYPEWRAPPER_SELECT_CATEGORY);
		typeWrappers.add(MiscHelper.TYPEWRAPPER_DO_CATEGORY);
		typeWrappers.add(MiscHelper.TYPEWRAPPER_ALIAS_CATEGORY);
	}

	protected boolean allRight() {
		return StringUtils.isNotBlank(newResultMap.getId()) && MiscHelper.getResultMapById(model.getSqlmap(), newResultMap.getId()) == null && StringUtils.isNotBlank(newResultMap.getClass_()) && resultWrappers.size() > 0;
	}
	public abstract void okPressed();
	public abstract void cancelPressed();
	@Override
	protected void doNotifyChanged(Notification notification) {
		
	}

	@Override
	protected void doPropertyChange(PropertyChangeEvent evt) {
		String pn = evt.getPropertyName();
		if (BatisSettingModel.K_SQLMAP.equals(pn)) {
			SqlMap new_map = (SqlMap) evt.getNewValue();
			MiscHelper.removeAndAddNewTypeAlias(typeWrappers, new_map.getTypeAlias());
			comboMapClassViewer.refresh();
			comboExtendsViewer.setInput(new_map.getResultMap());
		}
	}

	public void renew() {
		MiscHelper.disposeBinding(idBinding);
		MiscHelper.disposeBinding(groupByBinding);
		MiscHelper.disposeBinding(xmlNameBinding);
		
		newResultMap = Mapperv2Factory.eINSTANCE.createResultMap();
		resultWrappers.clear();
		initResultViewer();
		dynamicBinding(newResultMap,hostPage.bindingContext);
	}

	private void initResultViewer() {
		Connection conn = ProfileUtil.createConnection(model.getConnectionProfile(), null);
		if (model.getDtpStmt() instanceof QuerySelectStatement){
			Statement stmt = null;
			try {
				stmt = conn.createStatement();
				stmt.setFetchSize(1);
				ResultSet rs = stmt.executeQuery(model.getOpSql());
				ResultSetMetaData rs_meta = rs.getMetaData();
				int column_count = rs_meta.getColumnCount();
				for (int i = 1; i <= column_count; i++){
					Result one_result = Mapperv2Factory.eINSTANCE.createResult();
					one_result.setColumn(rs_meta.getColumnName(i));
					one_result.setColumnIndex(i);
					resultWrappers.add(new ResultWrapper(one_result));
				}
				rs.close();
				resultViewer.setInput(resultWrappers);
			} catch (SQLException e) {
				e.printStackTrace();
				hostPage.setErrorMessage("Error when reduce columns, cause: "+e.getLocalizedMessage());
			}finally{
				if (stmt != null){
					try {
						stmt.close();
					} catch (SQLException e) {
						e.printStackTrace();
					}
				}
			}
		}else{
			hostPage.setErrorMessage("Can't produce result items because current sql is not a SELECT clause!");
		}
	}

	private void dynamicBinding(ResultMap newmap, EMFDataBindingContext bindingContext) {
		ISWTObservableValue ob_control_id = SWTObservables.observeText(idValue, SWT.Modify);
		IObservableValue ob_model_id = EMFObservables.observeValue(newmap, Mapperv2Package.Literals.RESULT_MAP__ID);
		idBinding = bindingContext.bindValue(ob_control_id, ob_model_id);
		
		ISWTObservableValue ob_control_groupdy = SWTObservables.observeText(groupByValue, SWT.Modify);
		IObservableValue ob_model_groupby = EMFObservables.observeValue(newmap, Mapperv2Package.Literals.RESULT_MAP__GROUP_BY);
		groupByBinding = bindingContext.bindValue(ob_control_groupdy, ob_model_groupby);
		
		ISWTObservableValue ob_control_xmlname = SWTObservables.observeText(xmlNameValue, SWT.Modify);
		IObservableValue ob_model_xmlname = EMFObservables.observeValue(newmap, Mapperv2Package.Literals.RESULT_MAP__XML_NAME);
		xmlNameBinding = bindingContext.bindValue(ob_control_xmlname, ob_model_xmlname);
	}
}
